using System;
using System.Security.Cryptography;

namespace Zyg.Security
{
    internal class DecryptTransformer
    {
        #region Fields

        /// <summary>
        /// encryption algorithm
        /// </summary>
        private EncryptionAlgorithm algorithmID;

        /// <summary>
        /// initial vector
        /// </summary>
        private byte[] initVec;

        #endregion

        #region Properties

        /// <summary>
        /// Get or set the initial vector
        /// </summary>
        internal byte[] IV
        {
            get { return initVec; }
            set { initVec = value; }
        }

        #endregion

        #region Methods

        internal DecryptTransformer(EncryptionAlgorithm deCryptId)
        {
            algorithmID = deCryptId;
        }

        /// <summary>
        /// Get Crypto Service Provider
        /// </summary>
        /// <param name="bytesKey">private key</param>
        /// <returns>Crypto Transform</returns>
        internal ICryptoTransform GetCryptoServiceProvider(byte[] bytesKey)
        {
            switch (algorithmID)
            {
                case EncryptionAlgorithm.Des:
                    {
                        DES des = new DESCryptoServiceProvider();
                        des.Mode = CipherMode.CBC;

                        des.Key = bytesKey;
                        des.IV = initVec;

                        return des.CreateDecryptor();
                    }
                case EncryptionAlgorithm.TripleDes:
                    {
                        TripleDES des3 = new TripleDESCryptoServiceProvider();
                        des3.Mode = CipherMode.CBC;

                        return des3.CreateDecryptor(bytesKey, initVec);
                    }
                case EncryptionAlgorithm.Rc2:
                    {
                        RC2 rc2 = new RC2CryptoServiceProvider();
                        rc2.Mode = CipherMode.CBC;

                        return rc2.CreateDecryptor(bytesKey, initVec);
                    }
                case EncryptionAlgorithm.Rijndael:
                    {
                        Rijndael rijndael = new RijndaelManaged();
                        rijndael.Mode = CipherMode.CBC;

                        return rijndael.CreateDecryptor(bytesKey, initVec);
                    }
                default:
                    throw new CryptographicException("Algorithm " + algorithmID.ToString() + " is not supported yet.");
            }
        }

        #endregion
    }
}
